// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "WorldEntityMeta.h"
#include "WorldEntityProperty.h"
#include "WorldException.h"
//#include "WorldEntityReferencing.h"

class FWorldEntityReferencing;

/**
 * Base class to represent an element in the xml file.
 */
class FWorldEntityPart
	: public std::enable_shared_from_this<FWorldEntityPart>
{

public:

	using Ptr = std::shared_ptr<FWorldEntityPart>;
	using ConstPtr = std::shared_ptr<const FWorldEntityPart>;
	using WeakPtr = std::weak_ptr<FWorldEntityPart>;
	using ConstWeakPtr = std::weak_ptr<const FWorldEntityPart>;

public:

	FWorldEntityPart();
	FWorldEntityPart(FWorldEntityPart* parent, const pugi::xml_node& elem);
	virtual ~FWorldEntityPart();

	virtual void ToXml(pugi::xml_node& elem);

	WORLD_ENTITY_META_DECLARE(FWorldEntityPart)

	template<typename OtherT>
	bool IsA() const
	{
		return MetaClass().IsA(OtherT::sMetaClass());
	}

	template<typename OtherT>
	typename OtherT::Ptr As()
	{
		return std::static_pointer_cast<OtherT>(shared_from_this());
	}

protected:
	friend class FWorldEntityManager;
	friend class FWorldEntityPropertyBase;	// Receiving changed messages.
	friend class FWorldEntityReferencing;

	class XmlException : public FWorldException
	{
	public:
		XmlException(const char* what)
			: FWorldException(what)
		{}
	};

	virtual void Resolve(FWorldEntityReferencing& referencing);
	virtual void PropertyChanged();

protected:

	FWorldEntityPart*	_parent;
	pugi::xml_node		_xml;

};
